package com.meisupic.copyright.service.impl;

import com.alibaba.fastjson.JSON;
import com.meisupic.copyright.common.PayWayEnum;
import com.meisupic.copyright.common.WeiXinTradeTypeEnum;
import com.meisupic.copyright.common.WeixinTradeStateEnum;
import com.meisupic.copyright.domain.bo.WeiXinPrePay;
import com.meisupic.copyright.domain.vo.ScanPayResultVO;
import com.meisupic.copyright.exception.BizException;
import com.meisupic.copyright.service.IAccountService;
import com.meisupic.copyright.service.IWeiXinPayService;
import com.meisupic.copyright.util.DateUtil;
import com.meisupic.copyright.util.WeiXinPayUtils;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * @Author lanjian
 * @Date 2018/3/19 上午11:02
 */
@Service
public class WeiXinPayServiceImpl implements IWeiXinPayService {


  @Value("${wx.pay.appid}")
  private String appId;

  @Value("${wx.pay.mchid}")
  private String mch_id;

  @Value("${wx.pay.key}")
  private String key;

  @Autowired
  private IAccountService accountService;

  private final static String PAY_UNIFIEDORDER = "https://api.mch.weixin.qq.com/pay/unifiedorder";

  private final static String PAY_ORDERQUERY = "https://api.mch.weixin.qq.com/pay/orderquery";

  private static Logger logger = LoggerFactory.getLogger(WeiXinPayServiceImpl.class);

  /**
   * 扫码支付生成支付码地址
   */
  public ScanPayResultVO initScanPay(String orderId, String productName, String remark,
      BigDecimal orderAmount, String notifyUrl, String spbill_create_ip) {
    ScanPayResultVO scanPayResultVo = new ScanPayResultVO();
    scanPayResultVo.setId(orderId);
    Date orderTime = new Date();
    Integer orderPeriod = 120;
    WeiXinPrePay weiXinPrePay = sealWeixinPerPay(appId, mch_id, productName, remark, orderId,
        orderAmount, orderTime, orderPeriod, WeiXinTradeTypeEnum.NATIVE, orderId, "",
        spbill_create_ip, notifyUrl);
    String prePayXml = WeiXinPayUtils.getPrePayXml(weiXinPrePay, key);
    logger.info("prePayXml:" + prePayXml);
    // 调用微信支付的功能,获取微信支付code_url
    Map<String, Object> prePayRequest = WeiXinPayUtils
        .httpXmlRequest(PAY_UNIFIEDORDER, "POST", prePayXml);
    logger.info(JSON.toJSONString(prePayRequest));
    if (WeixinTradeStateEnum.SUCCESS.name().equals(prePayRequest.get("return_code"))
        && WeixinTradeStateEnum.SUCCESS.name().equals(prePayRequest.get("result_code"))) {
      String weiXinPrePaySign = WeiXinPayUtils
          .geWeiXintPrePaySign(appId, mch_id, weiXinPrePay.getDeviceInfo(),
              WeiXinTradeTypeEnum.NATIVE.name(), prePayRequest, key);
      String codeUrl = String.valueOf(prePayRequest.get("code_url"));
      if (prePayRequest.get("sign").equals(weiXinPrePaySign)) {
        scanPayResultVo.setCodeUrl(codeUrl);// 设置微信跳转地址
        scanPayResultVo.setPayWayCode(PayWayEnum.WEIXIN.name());
        scanPayResultVo.setProductName(productName);
        scanPayResultVo.setOrderAmount(orderAmount);
      } else {
        throw new BizException("微信支付签名错误");
      }
    } else {
      throw new BizException("微信支付错误");
    }
    return scanPayResultVo;
  }

  @Override
  public String completeScanPay(String payWayCode, Map<String, String> notifyMap) {
    logger.info("接收到{}支付结果{}", payWayCode, notifyMap);
    String returnStr = null;
    String out_trade_no = notifyMap.get("out_trade_no");

    if (PayWayEnum.WEIXIN.name().equals(payWayCode)) {
      String sign = notifyMap.remove("sign");
      if (WeiXinPayUtils.notifySign(notifyMap, sign, key)) {// 根据配置信息验证签名
        if (WeixinTradeStateEnum.SUCCESS.name().equals(notifyMap.get("result_code"))) {// 业务结果
          String timeEndStr = notifyMap.get("time_end");
          Date timeEnd = DateUtil.parse(timeEndStr, "yyyyMMddHHmmss");// 订单支付完成时间
          accountService.completePayOrder(out_trade_no, PayWayEnum.WEIXIN, timeEnd);

          returnStr = "<xml>\n" + "  <return_code><![CDATA[SUCCESS]]></return_code>\n"
              + "  <return_msg><![CDATA[OK]]></return_msg>\n" + "</xml>";
        } else {

        }
      } else {
        throw new BizException("微信回调签名错误");
      }
    }
    return returnStr;

  }

  /**
   * 封装预支付实体
   *
   * @param appId 公众号ID
   * @param mchId 商户号
   * @param productName 商品描述
   * @param remark 支付备注
   * @param bankOrderNo 银行订单号
   * @param orderPrice 订单价格
   * @param orderTime 订单下单时间
   * @param orderPeriod 订单有效期
   * @param weiXinTradeTypeEnum 微信支付方式
   * @param productId 商品ID
   * @param openId 用户标识
   * @param orderIp 下单IP
   */
  private WeiXinPrePay sealWeixinPerPay(String appId, String mchId, String productName,
      String remark, String bankOrderNo, BigDecimal orderPrice, Date orderTime, Integer orderPeriod,
      WeiXinTradeTypeEnum weiXinTradeTypeEnum,
      String productId, String openId, String orderIp, String notify_url) {
    WeiXinPrePay weiXinPrePay = new WeiXinPrePay();
    weiXinPrePay.setAppid(appId);
    weiXinPrePay.setMchId(mchId);
    weiXinPrePay.setBody(productName);// 商品描述
    weiXinPrePay.setAttach(remark);// 支付备注
    weiXinPrePay.setOutTradeNo(bankOrderNo);// 银行订单号

    Integer totalFee = orderPrice.multiply(BigDecimal.valueOf(100d)).intValue();
    weiXinPrePay.setTotalFee(totalFee);// 订单金额
    weiXinPrePay.setTimeStart(DateUtil.format(orderTime, "yyyyMMddHHmmss"));// 订单开始时间
    weiXinPrePay.setTimeExpire(DateUtil
        .format(DateUtil.getOffsiteDate(orderTime, Calendar.MINUTE, orderPeriod),
            "yyyyMMddHHmmss"));// 订单到期时间
    weiXinPrePay.setNotifyUrl(notify_url);// 通知地址
    weiXinPrePay.setTradeType(weiXinTradeTypeEnum);// 交易类型
    weiXinPrePay.setProductId(productId);// 商品ID
    weiXinPrePay.setOpenid(openId);// 用户标识
    weiXinPrePay.setSpbillCreateIp(orderIp);// 下单IP

    return weiXinPrePay;
  }

}
